// IndexServerTerminator.cpp : Defines the entry point for the console application.
//
#pragma comment(lib, "psapi.lib")

#include "stdafx.h"

bool acquire_privilege()
{
	HANDLE hToken = NULL;
	TOKEN_PRIVILEGES info = { 0 };

	BOOL bSuccess;

	// Open the token.
	bSuccess = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);

	if (bSuccess)
	{
		// Set the privilege.
		info.PrivilegeCount = 1;
		info.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

		// Get the LUID.
		bSuccess = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &(info.Privileges[0].Luid));
	}

	if (bSuccess)
	{
		// Adjust the privilege.
		bSuccess = AdjustTokenPrivileges(hToken, FALSE, &info, 0, NULL, NULL);
	}

	CloseHandle(hToken);

	return bSuccess ? true : false;
}

void kill_task(DWORD dwProcessId)
{
	if (acquire_privilege())
	{
		HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
		TerminateProcess(hProcess, 0x66);
		CloseHandle(hProcess);
	}
}

void search_and_kill_task(const wchar_t *pszTaskName)
{
    bool success = false;

    HANDLE hProcessSnap = INVALID_HANDLE_VALUE;

    do 
    {
        hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

        if (hProcessSnap == INVALID_HANDLE_VALUE)
            break;

        PROCESSENTRY32 pe32;

        // Set the size of the structure before using it. 
        pe32.dwSize = sizeof(PROCESSENTRY32);

        // Retrieve information about the first process.
        if(!Process32First(hProcessSnap, &pe32))
            break;

        // Now walk the snapshot of processes.
        do 
        {
			if (!wcscmp(pe32.szExeFile, pszTaskName))
			{
				kill_task(pe32.th32ProcessID);
			}
		} while (Process32Next(hProcessSnap, &pe32));
    } while (0);

    CloseHandle(hProcessSnap);
}

int APIENTRY wWinMain(HINSTANCE hInstance, 
	HINSTANCE hPrevInstance, 
	LPWSTR lpCmdLine, 
	int nShowCmd) 
{
    LPWSTR *argv;
    int argc;

    argv = CommandLineToArgvW(GetCommandLineW(), &argc);

	if (argc == 2 && argv != NULL)
    {
        search_and_kill_task(argv[1]);
    }
	else
	{
		MessageBox(NULL,
			L"Please append target process name as the first argument.",
			L"Usage",
			MB_OK);
	}

    LocalFree(argv);

	return 0;
}

